#pragma once
#include "requestor.hpp"

namespace bitrpc{
    namespace client{
// RpcCaller类：RPC调用器，提供友好的RPC调用接口
// 封装了请求的创建、发送和响应处理，支持三种调用方式：同步、异步和回调式
        class RpcCaller{
            public:
                using ptr = std::shared_ptr<RpcCaller>;

                using JsonAsyncResponse = std::future<Json::Value&>;                    // 异步JSON响应类型，用于获取异步调用结果
                using JsonResponseCallback = std::function<void(const Json::Value&)>;   // JSON回调函数类型，用于回调式调用

                // 构造函数：接收一个Requestor对象用于底层请求发送
                RpcCaller(const Requestor::ptr &requestor):_requestor(requestor){}

                // 同步RPC调用：发送请求后阻塞等待响应
                //【本质】：这里会发生阻塞，等待 onResponse 处理响应。由于使用的是同一个连接，
                // 内部通过 promise 对象来管理响应结果。RpcResponse 和 RpcRequest 都属于底层消息类型，
                // 它们与 onResponse 处理机制是统一的。当 onResponse 接收到响应并处理完成后，阻塞的同步调用就能获得最终结果。
                //其中回调函数也传入到response了，注册客户端这块 RequestDescribe 请求描述，记录一个RPC请求的所有信息，同时实际被调用了“if(rdp->callback) rdp->callback(msg);”
                bool call(const BaseConnection::ptr &conn, const std::string &method, 
                    const Json::Value &params, Json::Value &result) {

                    DLOG("开始同步rpc调用...");
                    // 1. 创建RPC请求消息
                    auto req_msg = MessageFactory::create<RpcRequest>();
                    req_msg->setId(UUID::uuid());                // 设置唯一请求ID
                    req_msg->setMType(MType::REQ_RPC);           // 设置消息类型为RPC请求
                    req_msg->setMethod(method);                  // 设置调用的方法名
                    req_msg->setParams(params);                  // 设置请求参数
                    BaseMessage::ptr rsp_msg;
                    
                    // 2. 发送请求并等待响应（同步调用）底层是一个关系，跟onresponnse是一个东西，可以获得结果，你onresponse获得结果
                    // ，这里阻塞之后也可以获得结果
                    bool ret = _requestor->send(conn, std::dynamic_pointer_cast<BaseMessage>(req_msg), rsp_msg);
                    if (ret == false) {
                        ELOG("同步Rpc请求失败!");
                        return false;
                    }
                    
                    DLOG("收到响应，进行解析，获取结果!");
                    // 3. 处理响应消息
                    auto rpc_rsp_msg = std::dynamic_pointer_cast<RpcResponse>(rsp_msg);
                    if (!rpc_rsp_msg) {
                        ELOG("rpc响应,向下类型转换失败!");
                        return false;
                    }
                    if (rpc_rsp_msg->rcode() != RCode::RCODE_OK) {
                        ELOG("rpc请求出错:%s", errReason(rpc_rsp_msg->rcode()));
                        return false;
                    }
                    
                    // 4. 提取结果并返回
                    result = rpc_rsp_msg->result();
                    DLOG("结果设置完毕！");
                    return true;
                }

                // 异步RPC调用：发送请求后立即返回，可以稍后通过future获取结果
                bool call(const BaseConnection::ptr &conn, const std::string &method, 
                    const Json::Value &params, JsonAsyncResponse &result) {
                    // 1. 创建请求
                    // 2. 调用 _requestor->send() 发送请求
                    // 3. send() 内部会阻塞等待响应
                    // 4. 当 Requestor::onResponse() 收到响应时，会设置 promise 值
                    // 5. send() 解除阻塞，返回响应消息
                    // 6. RpcCaller 解析响应，提取 JSON 结果

                    // 1. 创建RPC请求消息
                    auto req_msg = MessageFactory::create<RpcRequest>();
                    req_msg->setId(UUID::uuid());
                    req_msg->setMType(MType::REQ_RPC);
                    req_msg->setMethod(method);
                    req_msg->setParams(params);
                    
                    // 2. 创建promise对象，用于后续设置异步结果
                    auto json_promise = std::make_shared<std::promise<Json::Value>>();
                    result = json_promise->get_future();  // 获取关联的future对象返回给调用者
                    
                    // 3. 创建回调函数，用于处理响应
                    Requestor::RequestCallback cb = std::bind(&RpcCaller::Callback, 
                        this, json_promise, std::placeholders::_1);
                    
                    // 4. 发送异步请求
                    bool ret = _requestor->send(conn, std::dynamic_pointer_cast<BaseMessage>(req_msg), cb);
                    if (ret == false) {
                        ELOG("异步Rpc请求失败！");
                        return false;
                    }
                    return true;
                }

                // 回调式RPC调用：发送请求后立即返回，响应到达时自动调用回调函数
                bool call(const BaseConnection::ptr &conn, const std::string &method, 
                    const Json::Value &params, const JsonResponseCallback &cb) {
                    // 1. 创建请求和 promise
                    // 2. 创建回调函数 Callback，绑定到 promise
                    // 3. 调用 _requestor->send() 发送请求（回调模式）
                    // 4. 立即返回 future 给用户
                    // 5. 当响应到达时：Requestor::onResponse() → RpcCaller::Callback() → 设置 promise 值

                    // 1. 创建RPC请求消息
                    auto req_msg = MessageFactory::create<RpcRequest>();
                    req_msg->setId(UUID::uuid());
                    req_msg->setMType(MType::REQ_RPC);
                    req_msg->setMethod(method);
                    req_msg->setParams(params);

                    // 2. 创建回调函数，用于处理响应并调用用户回调
                    Requestor::RequestCallback req_cb = std::bind(&RpcCaller::Callback1, 
                        this, cb, std::placeholders::_1);
                    
                    // 3. 发送回调式请求
                    bool ret = _requestor->send(conn, std::dynamic_pointer_cast<BaseMessage>(req_msg), req_cb);
                    if (ret == false) {
                        ELOG("回调Rpc请求失败!");
                        return false;
                    }
                    return true;
                }
                
            private:
                // 处理回调式RPC请求的响应
                void Callback1(const JsonResponseCallback &cb, const BaseMessage::ptr &msg){
                // 1. 创建请求
                // 2. 创建回调函数 Callback1，绑定用户的回调
                // 3. 调用 _requestor->send() 发送请求（回调模式）
                // 4. 当响应到达时：Requestor::onResponse() → RpcCaller::Callback1() → 用户回调函数
                   
                    // 1. 将通用消息转换为RPC响应消息
                    auto rpc_rsp_msg = std::dynamic_pointer_cast<RpcResponse>(msg);
                    if (!rpc_rsp_msg) {
                        ELOG("rpc响应,向下类型转换失败！");
                        return;
                    }
                    
                    // 2. 检查RPC调用是否成功
                    if (rpc_rsp_msg->rcode() != RCode::RCODE_OK) {
                        ELOG("rpc回调请求出错:%s", errReason(rpc_rsp_msg->rcode()));
                        return;
                    }
                    
                    // 3. 调用用户的回调函数处理结果
                    cb(rpc_rsp_msg->result());
                }
                
                // 处理异步RPC请求的响应
                // @param result 用于设置异步结果的promise对象
                // @param msg 收到的RPC响应消息
                void Callback(std::shared_ptr<std::promise<Json::Value>> result, const BaseMessage::ptr &msg){
                    // 1. 将通用消息转换为RPC响应消息
                    auto rpc_rsp_msg = std::dynamic_pointer_cast<RpcResponse>(msg);
                    if(!rpc_rsp_msg){
                        ELOG("rpc响应,向下类型转换失败");
                        return;
                    }
                    
                    // 2. 检查RPC调用是否成功
                    if(rpc_rsp_msg->rcode() != RCode::RCODE_OK){
                        ELOG("rpc异步请求出错: %s", errReason(rpc_rsp_msg->rcode()));
                        return;
                    }
                    
                    // 3. 设置promise的值，解除相关future的阻塞
                    result->set_value(rpc_rsp_msg->result());
                }
                
            private:
                Requestor::ptr _requestor;  // 内部使用的请求发送器，负责底层通信
        };
    }
}

//方便外部，还是走上层走接口处理(存在发送和接收处理)，这层判断是否call成功即可。